﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using SelfManagement.Utility.Extensions;
using SelfManagement.Database.Common;

namespace SelfManagement.Database
{
    public interface IBaseRepository<T> : IDisposable where T : EntityBase, new()
    {
        T New();

        T Get(Expression<Func<T, bool>> predicate);

        IQueryable<T> Query(Expression<Func<T, bool>> predicate = null);

        bool Insert(T obj, bool saveChange = true);
        bool Update(T obj, Func<T, object[]> getKeys = null, bool saveChange = true, bool updateTime = true);
        bool Delete(T obj, bool saveChange = true);

        bool InsertBatch(IEnumerable<T> objs, bool saveChange = true);
        bool UpdateBatch(Expression<Func<T, bool>> predicate, Func<T, T> setter, bool saveChange = true);
        bool DeleteBatch(Expression<Func<T, bool>> predicate, bool saveChange = true);

        bool SaveChanges();
    }

    public static class IRepositoryExtensions
    {
        public static IQueryable<T> Query<T>(this IBaseRepository<T> repository) where T : EntityBase, new()
        {
            return repository.Query((entity) => true);
        }

        public static IQueryable<T> Query<T>(this IBaseRepository<T> repository, int pageIndex, int pageSize) where T : EntityBase, new()
        {
            return repository.Query((entity) => true).Paging(pageIndex, pageSize).AsQueryable();
        }

        public static IQueryable<T> Query<T>(this IBaseRepository<T> repository, Expression<Func<T, bool>> predicate, int pageIndex, int pageSize) where T : EntityBase, new()
        {
            return repository.Query(predicate).Paging(pageIndex, pageSize).AsQueryable();
        }
    }
}
